package com.qijian.flowable.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qijian.common.annotation.Log;
import com.qijian.common.annotation.PlugAnn;
import com.qijian.common.annotation.PlugParam;
import com.qijian.common.core.controller.BaseController;
import com.qijian.common.core.domain.AjaxResult;
import com.qijian.common.core.domain.entity.FlowablModelApproval;
import com.qijian.common.core.domain.entity.FlowableApproval;
import com.qijian.common.core.page.TableDataInfo;
import com.qijian.common.enums.ApprovalDescriptionEnum;
import com.qijian.common.enums.BusinessType;
import com.qijian.common.exception.ServiceException;
import com.qijian.common.utils.SecurityUtils;
import com.qijian.common.utils.StringUtils;
import com.qijian.common.utils.bean.BeanUtils;
import com.qijian.common.utils.mybatis.WhereEntityTool;
import com.qijian.common.utils.poi.ExcelUtil;
import com.qijian.flowable.domain.Flow;
import com.qijian.flowable.domain.FlowDetail;
import com.qijian.flowable.domain.query.FlowQuery;
import com.qijian.flowable.domain.vo.FlowDetailExportVo;
import com.qijian.flowable.domain.vo.FlowDetailVo;
import com.qijian.flowable.domain.vo.FlowVo;
import com.qijian.flowable.service.IFlowDetailService;
import com.qijian.flowable.service.IFlowService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 流程Controller
 *
 * @author qijian
 * @date 2024-03-01
 */
@Api(tags = "流程")
@RestController
@RequiredArgsConstructor
@RequestMapping("/business/flow")
public class FlowController extends BaseController {

    private final IFlowService flowService;

    private final IFlowDetailService flowDetailService;

    /**
     * 查询流程列表
     */

    @GetMapping("/list")
    public TableDataInfo list(FlowQuery query, Page<FlowVo> page) {
        initOrderItem(Flow.class, page.orders());
        query.setDataScope(true);
        if (CollectionUtil.isNotEmpty(query.getApprovalStatus())){
            if (query.getApprovalStatus().get(0).equals("U")){
                //查看自己发起的
                query.setUArr(Arrays.asList(query.getFlowType(),SecurityUtils.getUserId().toString()).stream().toArray(String[]::new));
                query.setU(null);
                query.setDataScope(null);
            }else if (query.getApprovalStatus().get(0).equals("I")){
                //查看自己审核的
                query.setIArr(Arrays.asList(query.getFlowType(),SecurityUtils.getUserId().toString(),SecurityUtils.getUserId().toString()).stream().toArray(String[]::new));
                query.setI(null);
                query.setDataScope(null);
            }else if (query.getApprovalStatus().get(0).equals("ALL")){
                //tood 是否包含自己的所有待确认
            }else {
                query.setApprove(query.getApprovalStatus());
            }
        }
        return getDataTable(flowService.pageVoCommon(page, WhereEntityTool.invoke(query)));
    }


    @GetMapping("/knifeList")
    public TableDataInfo knifeList(FlowQuery query, Page<FlowVo> page) {
        if (query != null && query.getAction() != null) {
            if (query.getAction().equals("新领")) {
                query.setAction("4");
            } else if (query.getAction().equals("以旧换新")) {
                query.setAction("8");
            } else if (query.getAction().equals("退库")) {
                query.setAction("7");
            } else {
                query.setAction(null);
            }
        }
        if (query != null && query.getCreateTime() != null) {
            query.getCreateTime()[0] = query.getCreateTime()[0] + " 00:00:01";
            query.getCreateTime()[1] = query.getCreateTime()[1] + " 23:59:59";
        }
        initOrderItem(Flow.class, page.orders());
        query.setDataScope(true);
        return getDataTable(flowService.pageVo(page, WhereEntityTool.invoke(query)));
    }


    @GetMapping("/knifeListNew")
    public TableDataInfo knifeListNew(FlowQuery query, Page<FlowVo> page) {
        query.setMainFlowType("flow_re_knife");
        if (query != null && query.getAction() != null) {
            if (query.getAction().equals("新领")) {
                query.setAction("4");
            } else if (query.getAction().equals("以旧换新")) {
                query.setAction("8");
            } else if (query.getAction().equals("退库")) {
                query.setAction("7");
            } else {
                query.setAction(null);
            }
        }
        if (query != null && query.getCreateTime() != null) {
            query.getCreateTime()[0] = query.getCreateTime()[0] + " 00:00:01";
            query.getCreateTime()[1] = query.getCreateTime()[1] + " 23:59:59";
        }
        initOrderItem(Flow.class, page.orders());
        query.setDataScope(true);
        return getDataTable(flowService.pageVoNew(page, WhereEntityTool.invoke(query)));
    }

    /**
     * 导出流程列表
     */

    @Log(title = "流程", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public void export(FlowQuery query, HttpServletResponse response) {
        new ExcelUtil<>(Flow.class).exportExcel(response, flowService.list(WhereEntityTool.invoke(query)), "流程数据");
    }

    /**
     * 获取流程详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(flowService.getInfoById(id));
    }


    /**
     * 获取流程详细信息
     */
    @GetMapping(value = "/knife/{id}")
    public AjaxResult getKnifeInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(flowService.getKnifeInfoById(id));
    }

    /**
     * 新增流程
     */
    @Log(title = "流程", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody FlowVo flowVo) {
        flowService.saveFlow(flowVo);
        return AjaxResult.success();
    }

    /**
     * 新增流程
     */
    @Log(title = "流程", businessType = BusinessType.INSERT)
    @PostMapping("/common")
    public AjaxResult commonAdd(@RequestBody FlowVo flowVo) {
        flowService.dealFlow(flowVo);
        return AjaxResult.success();
    }

    /**
     * 修改流程
     */
    @Log(title = "流程", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody FlowVo flowVo) {
        flowService.editFlow(flowVo);
        return AjaxResult.success();
    }

    /**
     * 修改流程
     */
    @Log(title = "流程", businessType = BusinessType.UPDATE)
    @PutMapping("/common")
    public AjaxResult commonEdit(@RequestBody FlowVo flowVo) {
        flowService.dealFlow(flowVo);
        return AjaxResult.success();
    }

    /**
     * 删除流程
     */
    @Log(title = "流程", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable List<Long> ids) {
        ids.forEach(id -> approval(flowService.getById(id)));
        flowDetailService.remove(new LambdaQueryWrapper<FlowDetail>().in(FlowDetail::getMainId, ids));
        return toAjax(flowService.removeByIds(ids));
    }

    /**
     * 单据提交审核
     */
    @Log(title = "流程", businessType = BusinessType.APPROVAL)
    @PlugAnn(groupClass = FlowableApproval.Approval.class, params = {"'flow_equipment_ledger'", "T(com.qijian.common.utils.SecurityUtils).getUserId()", "T(com.qijian.common.utils.SecurityUtils).getDeptId()", "T(com.qijian.common.utils.SecurityUtils).getNickName()", "T(com.qijian.common.utils.SecurityUtils).getDeptName()"})
    @GetMapping(value = "/approval/{id}")
    public AjaxResult approval(@PlugParam @PathVariable("id") Long id) {
        approval(flowService.getById(id));
        Flow flowChange = new Flow();
        flowChange.setId(id);
        flowChange.setCreateById(SecurityUtils.getUserId());
        flowChange.setApprovalStatus(ApprovalDescriptionEnum.B);
        return AjaxResult.success(flowService.updateById(flowChange));
    }


    @Log(title = "通用流程", businessType = BusinessType.APPROVAL)
    @PlugAnn(groupClass = FlowablModelApproval.Approval.class, params = {"'flow_equipment_ledger'", "T(com.qijian.common.utils.SecurityUtils).getUserId()", "T(com.qijian.common.utils.SecurityUtils).getDeptId()", "T(com.qijian.common.utils.SecurityUtils).getNickName()", "T(com.qijian.common.utils.SecurityUtils).getDeptName()"})
    @PostMapping(value = "/approval")
    public AjaxResult approval1(@PlugParam @RequestBody FlowVo flowVo) {
        if (ObjectUtil.isNull(flowVo)) {
            throw new ServiceException("单据信息为空");
        }
        if (StringUtils.isEmpty(flowVo.getFlowType())) {
            throw new ServiceException("流程key为空");
        }
        if (CollectionUtils.isNotEmpty(flowVo.getDetails()) && !flowVo.getMainFlowType().startsWith("flow_re_knife")) {
            flowService.saveFlow(flowVo);
        }
        if (flowVo.getMainFlowType().startsWith("flow_re_knife")) {
            flowService.saveFlowKnife(flowVo);
        }
        return AjaxResult.success();
    }

    @Log(title = "通用流程", businessType = BusinessType.APPROVAL)
    @PlugAnn(groupClass = FlowablModelApproval.Approval.class, params = {"'flow_fin_cost_ex'", "T(com.qijian.common.utils.SecurityUtils).getUserId()", "T(com.qijian.common.utils.SecurityUtils).getDeptId()", "T(com.qijian.common.utils.SecurityUtils).getNickName()", "T(com.qijian.common.utils.SecurityUtils).getDeptName()"})
    @PostMapping(value = "/common/approval")
    public AjaxResult finApproval(@PlugParam @RequestBody FlowVo flowVo) {
        if (ObjectUtil.isNull(flowVo)) {
            throw new ServiceException("单据信息为空");
        }
        if (StringUtils.isEmpty(flowVo.getFlowType())) {
            throw new ServiceException("流程key为空");
        }

        if (CollectionUtils.isNotEmpty(flowVo.getDetails())) {
            throw new ServiceException("E01:流程明细为空");
        }
        flowService.checkFlow(flowVo);
        flowService.dealFlow(flowVo);
        return AjaxResult.success();
    }


    /**
     * 单据提交审核
     */
    @Log(title = "流程", businessType = BusinessType.APPROVAL)
    @PlugAnn(groupClass = FlowablModelApproval.Approval.class, params = {"'flow_fin_cost_ex'", "T(com.qijian.common.utils.SecurityUtils).getUserId()", "T(com.qijian.common.utils.SecurityUtils).getDeptId()", "T(com.qijian.common.utils.SecurityUtils).getNickName()", "T(com.qijian.common.utils.SecurityUtils).getDeptName()"})
    @GetMapping(value = "/common/approval/{ids}")
    public AjaxResult finApproval(@PlugParam @PathVariable("ids") List<Long> ids) {
        ids.stream().forEach(id->{
            FlowVo flowVo = flowService.getInfoById(id);
            approval(flowVo);
            // 校验 是否审核
            flowService.checkFlow(flowVo);
            Flow flowChange = new Flow();
            flowChange.setId(id);
            flowChange.setCreateById(SecurityUtils.getUserId());
            flowChange.setApprovalStatus(ApprovalDescriptionEnum.B);
            flowService.updateById(flowChange);
        });
        return AjaxResult.success();
    }

    @Log(title = "刀具流程记录导出", businessType = BusinessType.EXPORT)
    @GetMapping("/exportKnifeRecord")
    public void exportKnifeRecord(FlowQuery query, HttpServletResponse response) {
        Page<FlowVo> page = new Page<>();
        page.setSize(-1);
        query.setFlowType(null);
        query.setMainFlowType("flow_re_knife");
        if (query != null && query.getAction() != null) {
            if (query.getAction().equals("新领")) {
                query.setAction("4");
            } else if (query.getAction().equals("以旧换新")) {
                query.setAction("8");
            } else if (query.getAction().equals("退库")) {
                query.setAction("7");
            } else {
                query.setAction(null);
            }
        }
        if (query != null && query.getCreateTime() != null) {
            query.getCreateTime()[0] = query.getCreateTime()[0] + " 00:00:01";
            query.getCreateTime()[1] = query.getCreateTime()[1] + " 23:59:59";
        }
        initOrderItem(Flow.class, page.orders());
        Page<FlowDetailVo> result = flowService.pageVoNew(page, WhereEntityTool.invoke(query));
        List<FlowDetailVo> records = result.getRecords();
        List<FlowDetailExportVo> flowDetailExportVos = new ArrayList<>();
        for (FlowDetailVo record : records) {
            FlowDetailExportVo flowDetailExportVo = BeanUtils.copyProperties(record, FlowDetailExportVo.class);
            flowDetailExportVo.setCreateBy(record.getFlow().getCreateBy());
            flowDetailExportVo.setProjects(record.getFlow().getProjects());
            flowDetailExportVo.setEqpName(record.getFlow().getEqpName());
            flowDetailExportVo.setApprovalTime(record.getFlow().getApprovalTime());
            flowDetailExportVos.add(flowDetailExportVo);
        }
        new ExcelUtil<>(FlowDetailExportVo.class).exportExcel(response, flowDetailExportVos, "刀具流程记录");
    }


}
